
#ifndef MSGUTILS_BIT_READER_H
#define MSGUTILS_BIT_READER_H

// sys
#include <stdint.h>
#include <stddef.h>
// mine
#include "common.h"
#include "error.h"

namespace msgutils {

class BitReader {
 public:
  BitReader(IReadBuffer* read_buffer);

  BitReader(const uint8_t* buffer, size_t size);

  template<size_t size>
  BitReader(const uint8_t (&buffer)[size]);

  ~BitReader(void);

  template<class T>
  BitReader& operator>>(T& val);

  template<class T>
  size_t GetBlock(T* block, size_t size);

  size_t BytesRead(void) const;

 private:
  template<class T, bool is_arithmetic>
  friend struct ReadDispatch;

  template<class T>
  void Read(T& val); 

  void Read(char* string);

  template<size_t size>
  void Read(char (&string)[size]);

  void Construct(const uint8_t* buffer, size_t size);

  size_t DecodeNumber(size_t bits, void* number_addr, bool drain);

 private:
  IReadBuffer* rbuf_;
  bool delete_rbuf_;
};

#include "bit_reader-inl.h"

}

#endif // MSGUTILS_BIT_READER_H

